package com.cn.fw4j.container.impl;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cn.fw4j.container.inter.IContainerObserver;
import com.cn.fw4j.container.inter.IController;
import com.cn.fw4j.json.annotation.JSON;
import com.cn.fw4j.mvc.annotation.Fw4jController;
import com.cn.fw4j.mvc.annotation.DELETE;
import com.cn.fw4j.mvc.annotation.GET;
import com.cn.fw4j.mvc.annotation.POST;
import com.cn.fw4j.mvc.annotation.PUT;
import com.cn.fw4j.util.ParseClassPackageHelper;

/**
 * 
 * @author 穆仁超
 *
 */
public class JavaController implements IContainerObserver,IController {
	
	private final static Logger logger = LoggerFactory.getLogger(JavaController.class);
	
	private final Map<String,String> gets = new HashMap<String,String>();
	private final Map<String,String> posts = new HashMap<String,String>();
	private final Map<String,String> puts = new HashMap<String,String>();
	private final Map<String,String> deletes = new HashMap<String,String>();
	
	private final static JavaController instance = new JavaController();
	
	private JavaController(){}
	
	public static JavaController getInstance(){
		return instance;
	}
	
	@Override
	public void add(String path) {
		if (path.endsWith(".class") && path.indexOf("bin-groovy") == -1) {
			try {
				logger.info(path);
				String name = ParseClassPackageHelper.getPackage(path).replace("/", ".");
				ClassLoader cll = Thread.currentThread().getContextClassLoader();
				Class<?> cl = cll.loadClass(name);
				if(cl.getAnnotation(Fw4jController.class)!=null){
					addController(cl);
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	private void addController(Class<?> cl){
		Fw4jController ctrl = cl.getAnnotation(Fw4jController.class);
		Method[] ms = cl.getMethods();
		this.method(ctrl.value(),ms,cl.getCanonicalName());
	}
	private void method(String basePath,Method[] ms,String packageName){
		for(Method m : ms){
			StringBuilder url = new StringBuilder();
			StringBuilder pm = new StringBuilder(packageName);
			GET get = m.getAnnotation(GET.class);
			POST post = m.getAnnotation(POST.class);
			PUT put = m.getAnnotation(PUT.class);
			DELETE delete = m.getAnnotation(DELETE.class);
			JSON json = m.getAnnotation(JSON.class);
			if(get != null){
				url.append("GET$");
				url.append(basePath);
				url.append(get.value());
				pm.append("$");
				pm.append(m.getName());
				if(json != null){
					pm.append("$JSON:");
					pm.append(json.value());
				}
				logger.info(url.toString()+">>"+pm.toString());
				gets.put(url.toString(), pm.toString());
			}else if(post != null){
				url.append("POST$");
				url.append(basePath);
				url.append(post.value());
				pm.append("$");
				pm.append(m.getName());
				if(json != null){
					pm.append("$JSON:");
					pm.append(json.value());
				}
				logger.info(url.toString()+">>"+pm.toString());
				posts.put(url.toString(), pm.toString());
			}else if(put != null){
				url.append("PUT$");
				url.append(basePath);
				url.append(put.value());
				pm.append("$");
				pm.append(m.getName());
				if(json != null){
					pm.append("$JSON:");
					pm.append(json.value());
				}
				logger.info(url.toString()+">>"+pm.toString());
				puts.put(url.toString(), pm.toString());
			}else if(delete != null){
				url.append("DELETE$");
				url.append(basePath);
				url.append(delete.value());
				pm.append("$");
				pm.append(m.getName());
				if(json != null){
					pm.append("$JSON:");
					pm.append(json.value());
				}
				logger.info(url.toString()+">>"+pm.toString());
				deletes.put(url.toString(), pm.toString());
			}
		}
	}
		
	@Override
	public String gets(String key) {
		return gets.get(key);
	}
	@Override
	public String posts(String key) {
		return posts.get(key);
	}
	@Override
	public String puts(String key) {
		return puts.get(key);
	}
	@Override
	public String deletes(String key) {
		return deletes.get(key);
	}
	
}
